package com.example.mydemo;

import android.Manifest;
import android.annotation.SuppressLint;
import android.content.Context;
import android.graphics.ImageFormat;
import android.graphics.SurfaceTexture;
import android.hardware.camera2.CameraAccessException;
import android.hardware.camera2.CameraCaptureSession;
import android.hardware.camera2.CameraCharacteristics;
import android.hardware.camera2.CameraDevice;
import android.hardware.camera2.CameraManager;
import android.hardware.camera2.CaptureRequest;
import android.hardware.camera2.CaptureResult;
import android.hardware.camera2.TotalCaptureResult;
import android.media.Image;
import android.media.ImageReader;
import android.os.Bundle;
import android.util.Log;
import android.util.Size;
import android.view.Surface;
import android.view.TextureView;
import android.widget.Toast;

import com.example.mydemo.base.BaseActivity;
import java.nio.ByteBuffer;
import java.util.Arrays;
import java.util.List;

public class SubCameraActivity extends BaseActivity {
    private static final int PERMISSION_REQUEST_CODE = 1109;
    CameraManager cameraManager;//相机管理类
    String cameraId = "0";//相机id
    List<Size> outputSizes;//相机输出尺寸
    Size previewSize;//预览尺寸
    TextureView previewView;
//    TextureView previewView;//自适应相机预览view
//    private TextureView textureView;  //预览框控件
    ImageReader previewReader;
    CameraCaptureSession cameraCaptureSession;//相机会话类
    CameraDevice cameraDevice;//相机设备类
    int sizeIndex = 0;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_sub_camera);
        previewView = findViewById(R.id.afttv_camera);
        boolean flag = previewView.isAvailable();
        Log.d("lfy","[SubCameraActivity] onCreate...flag="+flag);
        previewView.setSurfaceTextureListener(surfaceTextureListener);


        //初始化工具类，把Context挂载上去
        cameraManager = (CameraManager) getApplicationContext().getSystemService(Context.CAMERA_SERVICE);
        cameraId = getCameraId(false);//默认使用后置相机

    }

    public String getCameraId(boolean useFront){
        try {
            for (String cameraId : cameraManager.getCameraIdList()){
                CameraCharacteristics characteristics = cameraManager.getCameraCharacteristics(cameraId);
                int cameraFacing = characteristics.get(CameraCharacteristics.LENS_FACING);
                if (useFront){
                    if (cameraFacing == CameraCharacteristics.LENS_FACING_FRONT){
                        return cameraId;
                    }
                }else {
                    if (cameraFacing == CameraCharacteristics.LENS_FACING_BACK){
                        return cameraId;
                    }
                }
            }
        } catch (CameraAccessException e) {
            e.printStackTrace();
        }
        return null;
    }

    @Override
    public void onResume() {
        super.onResume();
        Log.d("lfy","[SubCameraActivity] onResume......");
        this.requestPermission("请给予相机、存储权限，以便app正常工作",
                new BaseActivity.Callback() {
                    @Override
                    public void success() {
                        if (previewView.isAvailable()) {
                            openCamera();
                        } else {
                            Log.d("lfy","[SubCameraActivity] onResume...setSurfaceTextureListener...");
                            previewView.setSurfaceTextureListener(surfaceTextureListener);
                        }
                    }

                    @Override
                    public void failed() {
                        Toast.makeText(getApplicationContext(), "未授予相机、存储权限！", Toast.LENGTH_SHORT).show();
                    }
                },
                new String[]{Manifest.permission.CAMERA, Manifest.permission.WRITE_EXTERNAL_STORAGE});

//        ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.CAMERA, Manifest.permission.WRITE_EXTERNAL_STORAGE},
//                PERMISSION_REQUEST_CODE);
//        if (previewView.isAvailable()) {
//            openCamera();
//        } else {
//            previewView.setSurfaceTextureListener(surfaceTextureListener);
//        }
    }

    TextureView.SurfaceTextureListener surfaceTextureListener = new TextureView.SurfaceTextureListener() {
        //TextureView 可用时调用改回调方法
        @Override
        public void onSurfaceTextureAvailable(SurfaceTexture surface, int width, int height) {
            //TextureView 可用，打开相机
            Log.d("lfy","[SubCameraActivity] onSurfaceTextureAvailable......");
            previewView.setSurfaceTextureListener(this);
            openCamera();
        }

        @Override
        public void onSurfaceTextureSizeChanged(SurfaceTexture surface, int width, int height) {
            Log.d("lfy","[SubCameraActivity] onSurfaceTextureSizeChanged......");
        }

        @Override
        public boolean onSurfaceTextureDestroyed(SurfaceTexture surface) {
            Log.d("lfy","[SubCameraActivity] onSurfaceTextureDestroyed...");
            return false;
        }

        @Override
        public void onSurfaceTextureUpdated(SurfaceTexture surface) {
            Log.d("lfy","[SubCameraActivity] onSurfaceTextureUpdated......");
        }
    };

    @Override
    public void onPause() {
        super.onPause();
        releaseCamera();
    }

    /**
     * 释放相机资源
     * @param cameraDevice
     */
    public void releaseCameraDevice(CameraDevice cameraDevice){
        if (cameraDevice != null){
            cameraDevice.close();
            cameraDevice = null;
        }
    }

    /**
     * 关闭相机会话
     * @param session
     */
    public void releaseCameraSession(CameraCaptureSession session){
        if (session != null){
            session.close();
            session = null;
        }
    }

    /**
     * 关闭 ImageReader
     * @param reader
     */
    public void releaseImageReader(ImageReader reader){
        if (reader != null){
            reader.close();
            reader = null;
        }
    }

    private void releaseCamera() {
        releaseImageReader(previewReader);
        releaseCameraSession(cameraCaptureSession);
        releaseCameraDevice(cameraDevice);
    }

    private void createPreviewSession() {
        //关闭之前的会话
        releaseImageReader(previewReader);
        releaseCameraSession(cameraCaptureSession);
        //根据TextureView 和 选定的 previewSize 创建用于显示预览数据的Surface
        SurfaceTexture surfaceTexture = previewView.getSurfaceTexture();
        Log.d("lfy","[PreviewFragment] createPreviewSession...surfaceTexture="+surfaceTexture);
        surfaceTexture.setDefaultBufferSize(800, 600);//设置SurfaceTexture缓冲区大小
        final Surface previewSurface = new Surface(surfaceTexture);
        //获取 ImageReader 和 surface
        previewReader = ImageReader.newInstance(800, 600, ImageFormat.JPEG, 2);
        previewReader.setOnImageAvailableListener(
            new ImageReader.OnImageAvailableListener() {
                @Override
                public void onImageAvailable(ImageReader reader) {
                    Image image = reader.acquireLatestImage();
                    if (image != null) {
                        ByteBuffer buffer = image.getPlanes()[0].getBuffer();
                        byte[] data = new byte[buffer.remaining()];
                        Log.d("lfy", "data-size=" + data.length);
                        buffer.get(data);
                        image.close();
                    }
                }
            },
            null);
        final Surface readerSurface = previewReader.getSurface();

        try {
            //创建预览session
            cameraDevice.createCaptureSession(Arrays.asList(previewSurface, readerSurface),
                    new CameraCaptureSession.StateCallback() {
                        @Override
                        public void onConfigured(CameraCaptureSession session) {

                            cameraCaptureSession = session;

                            try {
                                //构建预览捕获请求
                                CaptureRequest.Builder builder = cameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
                                builder.addTarget(previewSurface);//设置 previewSurface 作为预览数据的显示界面
                                builder.addTarget(readerSurface);
                                CaptureRequest captureRequest = builder.build();
                                //设置重复请求，以获取连续预览数据
                                session.setRepeatingRequest(captureRequest, new CameraCaptureSession.CaptureCallback() {
                                            @Override
                                            public void onCaptureProgressed(CameraCaptureSession session, CaptureRequest request, CaptureResult partialResult) {
                                                super.onCaptureProgressed(session, request, partialResult);
                                            }

                                            @Override
                                            public void onCaptureCompleted(CameraCaptureSession session, CaptureRequest request, TotalCaptureResult result) {
                                                super.onCaptureCompleted(session, request, result);
                                            }
                                        },
                                        null);
                            } catch (CameraAccessException e) {
                                e.printStackTrace();
                            }
                        }

                        @Override
                        public void onConfigureFailed(CameraCaptureSession session) {

                        }
                    },
                    null);
        } catch (CameraAccessException e) {
            e.printStackTrace();
        }

    }

    @SuppressLint("MissingPermission")
    private void openCamera() {
        try {
            //打开相机
            cameraManager.openCamera(cameraId,
                new CameraDevice.StateCallback() {
                    @Override
                    public void onOpened(CameraDevice camera) {
                        if (camera == null) {
                            return;
                        }
                        cameraDevice = camera;
                        //创建相机预览 session
                        createPreviewSession();
                    }

                    @Override
                    public void onDisconnected(CameraDevice camera) {
                        //释放相机资源
                        releaseCamera();
                    }

                    @Override
                    public void onError(CameraDevice camera, int error) {
                        //释放相机资源
                        releaseCamera();
                    }
                },
                null);
        } catch (CameraAccessException e) {
            e.printStackTrace();
        }
    }
}
